/**
 * 创建 threejs 四大天王
 * 场景、相机、渲染器、控制器
 */

import * as THREE from 'three';
import {
  OrbitControls
} from "three/examples/jsm/controls/OrbitControls";

export class Basic {
  public scene: THREE.Scene;
  public camera: THREE.PerspectiveCamera;
  public renderer: THREE.WebGLRenderer
  public controls: OrbitControls;
  public dom: HTMLElement;
  public mouseX: number | null;
  public mouseY: number | null;
  constructor(dom: HTMLElement) {
    this.dom = dom
    this.mouseX = this.mouseY = 0;
    this.initScenes()
    this.initAxesHelper()
    // this.initZoom()
    this.setControls()
    this.render();
  }


  //初始化辅助坐标系
  initAxesHelper() {
    const axes = new THREE.AxesHelper(80);
    this.scene.add(axes);
    this.renderer.render(this.scene, this.camera);
  }

  /**
   * 初始化场景
   */
  initScenes() {
    this.scene = new THREE.Scene();

    this.camera = new THREE.PerspectiveCamera(
      45,
      window.innerWidth / window.innerHeight,
      1,
      100000
    );
    // this.camera.position.set(0, 30, -250);
    this.camera.position.set(0, 0, 220);
    // 创建平行光源
    const light = new THREE.DirectionalLight();
    light.position.set(0, 0, 1);
    const light2 = new THREE.DirectionalLight();
    light.position.set(0, 0, -1);
    this.scene.add(light);
    this.scene.add(light2)
    // // 创建点光源
    const point = new THREE.PointLight(0xeeeeee);
    point.position.set(200, 400, 300); //点光源位置
    const point2 = new THREE.PointLight(0xeeeeee);
    point2.position.set(400, 200, -300); //点光源位置
    this.scene.add(point); //点光源添加到场景中
    this.scene.add(point2); //点光源添加到场景中


    this.renderer = new THREE.WebGLRenderer({
      alpha: true, // 透明
      antialias: true, // 抗锯齿
      preserveDrawingBuffer: true,
    });
    this.renderer.setPixelRatio(window.devicePixelRatio); // 设置屏幕像素比
    this.renderer.setSize(window.innerWidth, window.innerHeight); // 设置渲染器宽高
    this.dom.appendChild(this.renderer.domElement); // 添加到dom中
  }

  //实现鼠标移入地球放大缩小的特效
  initZoom = ()=> {
    document.addEventListener("mousemove", this.onMouseMove);
    document.addEventListener("touchmove", this.onTouchMove);
  }
  //计算相机的位置
  coordinates = (clientX, clientY)=> {
    const limit = 270;
    const limitNeg = limit * -1;

    this.mouseX = clientX - window.innerWidth / 2;
    this.mouseY = clientY - window.innerHeight / 2;

    this.mouseX = this.mouseX >= limit ? limit : this.mouseX;
    this.mouseX = this.mouseX <= limitNeg ? limitNeg : this.mouseX;

    this.mouseY = this.mouseY >= limit ? limit : this.mouseY;
    this.mouseY = this.mouseY <= limitNeg ? limitNeg : this.mouseY;
    //变更相机的位置
    this.camera.position.x += (this.mouseX * -1 - this.camera.position.x) * 0.05;
    this.camera.position.y += (this.mouseY - this.camera.position.y) * 0.05;
    this.camera.lookAt(this.scene.position); //相机需要观察的坐标
  }
  //web上的鼠标事件
  onMouseMove= (e)=> {
    this.coordinates(e.clientX, e.clientY);
  }
  //移动端的触屏事件
  onTouchMove = (e)=> {
    const touchX = e.changedTouches[0].clientX;
    const touchY = e.changedTouches[0].clientY;
    this.coordinates(touchX, touchY);
  }

  /**
   * 设置控制器
   */
  setControls() {
    // 鼠标控制      相机，渲染dom
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);

    this.controls.autoRotateSpeed = 3
    // 使动画循环使用时阻尼或自转 意思是否有惯性
    this.controls.enableDamping = true;
    // 动态阻尼系数 就是鼠标拖拽旋转灵敏度
    this.controls.dampingFactor = 0.05;
    // 是否可以缩放
    this.controls.enableZoom = true;
    // 设置相机距离原点的最远距离
    this.controls.minDistance = 100;
    // 设置相机距离原点的最远距离
    this.controls.maxDistance = 300;
    // 是否开启右键拖拽
    this.controls.enablePan = false;
  }
  render = () => {
    this.renderer.render(this.scene, this.camera);
    requestAnimationFrame(this.render);
  }
}